package de.sendorian.app.forumArchive.download;

import java.io.IOException;
import java.util.List;

import javax.annotation.Nonnull;

import org.apache.log4j.Logger;

import de.sendorian.app.forumArchive.domain.File;
import de.sendorian.app.forumArchive.domain.Topic;


/**
 * Performs a download of the given file and does a retry if this failes. This
 * class is not aware of already downloaded files.
 * 
 * @author sendorian
 * 
 */
public abstract class DownloadTaskBase implements DownloadTask, Runnable {
    private static final Logger logger = Logger.getLogger(DownloadTaskBase.class);

    protected File file;
    protected Topic topic;
    protected List<String> filesInArchives;


    protected DownloadTaskBase(@Nonnull File file, @Nonnull final Topic topic, @Nonnull List<String> filesInArchives) {
        this.file = file;
        this.topic = topic;
        this.filesInArchives = filesInArchives;
    }


    public void run() {
        try {
            downloadFile();
        } catch (RuntimeException e) {
            // catch any unexpected exception because the Sheduler cannot deal
            // with it
            logger.error("Unexpected exception occured", e);
        }
    }


    /*
     * (non-Javadoc)
     * 
     * @see de.sendorian.app.forumArchive.download.DownloadTask#downloadFile()
     */
    public boolean downloadFile() {
        if (file.existsLocally()) {
            logger.info("Skipping file " + file.getName() + " from topic \"" + topic.getName()
                    + "\". It already exists.");
            return false;
        }

        logger.info("Downloading file " + file.getName() + " from topic \"" + topic.getName() + "\"");
        boolean downloaded = false;

        try {
            downloaded = file.save();
        } catch (IOException e) {
            int downloadCount = 1;

            // retry
            while (downloadCount < 5) {
                logger.warn("Failure downloading file " + file.getName() + ". Trying again (" + (downloadCount + 1)
                        + ").");
                try {
                    // delete already downloaded, potentially corrupted version
                    file.deleteLocalVersion();

                    downloaded = file.save();
                    // if no exception occurs, finish retry
                    break;
                } catch (IOException e2) {
                    if (downloadCount >= 5) {
                        logger.error("Error downloading file " + file.getUrl() + " in topic \"" + topic.getName()
                                + "\" (" + topic.getUrl() + ")" + ". Download failed " + downloadCount
                                + " times. This is a permanent error.", e);
                    }
                }
                downloadCount++;
            }
        }
        if (downloaded) {
            logger.info("Successfully downloaded file " + file.getName() + " from topic \"" + topic.getName() + "\"");
        } else {
            logger.error("The file " + file.getName() + " from topic \"" + topic.getName() + "\" was NOT downloaded.");
        }
        return downloaded;
    }

}
